package game

import (
	"fmt"
	"reflect"
	"server/GoUtil"
	"server/MergeConst"
	"server/game/internal"
	"strings"
	"time"

	"server/msg"

	"google.golang.org/protobuf/proto"
	"server/pkg/github.com/name5566/leaf/db/mongodb"
	"server/pkg/github.com/name5566/leaf/gate"
	"server/pkg/github.com/name5566/leaf/log"

	"server/db"
)

var (
	Module  = new(internal.Module)
	ChanRPC = internal.ChanRPC
	MongoDB *mongodb.DialContext
)

func handler(m interface{}, h interface{}) {
	Module.Skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
}

func RegisterHandlerRPC(param []interface{}) {
	handler(&msg.ClientReq{}, HandleClientReq)
}

func init() {
	db.InitDB()
	// db.InitRedis()
	// db.TestGetAllKey()
	GoUtil.RegisterEvent("GameModuleOnInit", RegisterHandlerRPC, nil)
	G_getGameLogic()
}

func HandleClientReq(args []interface{}) {

	m := args[0].(*msg.ClientReq)
	// 消息的发送者
	a := args[1].(gate.Agent)
	_, ok := internal.Agents[a]
	if ok {
		log.Debug("消息的发送者")
	}
	buf := m.GetInfo()
	log.Debug("消息Func", m.GetFunc())
	fmt.Println("消息Func:", m.GetFunc())
	switch m.GetFunc() {
	case "ClientTick":
		log.Debug("消息ClientTick")
	case "ReqServerVersion":
		G_GameLogicPtr.SendServerVersion(a)
	case "ReqRegisterAccount":
		detail := &msg.ReqRegisterAccount{}
		proto.Unmarshal(buf, detail)
		gl := G_getGameLogic()
		if gl.IsExsitAccount(detail.UserName) {
			ResRegisterAccount := &msg.ResRegisterAccount{}
			ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Exist
			data, _ := proto.Marshal(ResRegisterAccount)
			gl.PackResInfo(a, "ResRegisterAccount", data)
			break
		}
		if strings.Count(detail.UserName, "")-1 < 6 {
			ResRegisterAccount := &msg.ResRegisterAccount{}
			ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_Short
			data, _ := proto.Marshal(ResRegisterAccount)
			gl.PackResInfo(a, "ResRegisterAccount", data)

			break
		}
		gl.Db_AccountInfo.UserName = detail.UserName
		gl.Db_AccountInfo.UserPassword = detail.UserPwd
		if gl.NewAccountInsertDataToDB() == false {
			ResRegisterAccount := &msg.ResRegisterAccount{}
			ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Fail
			data, _ := proto.Marshal(ResRegisterAccount)
			gl.PackResInfo(a, "ResRegisterAccount", data)

			break
		}
		ResRegisterAccount := &msg.ResRegisterAccount{}
		ResRegisterAccount.ResultCode = 0
		data, _ := proto.Marshal(ResRegisterAccount)
		gl.PackResInfo(a, "ResRegisterAccount", data)
	case "ReqLogin":
		detail := &msg.ReqLogin{}
		proto.Unmarshal(buf, detail)
		accountInfo := db.GetAccountInfoFromDb(detail.UserName)
		ResLogin := &msg.ResLogin{}
		if accountInfo != nil {
			if accountInfo.UserPassword == detail.UserPwd {
				playerbaseinfo := db.GetPlayerBaseInfoFromDbByName(detail.UserName)
				if playerbaseinfo != nil {

					ResLogin.ResultCode = 0
					ResLogin.DwUin = playerbaseinfo.DwUin
					ResLogin.FaceBookId = playerbaseinfo.FaceBookId
					ResLogin.UserName = playerbaseinfo.UserName
				} else {
					ResLogin.ResultCode = MergeConst.Protocol_Error_Account_NoExsit
					ResLogin.DwUin = 0
				}
			} else {
				ResLogin.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_ERROR
				ResLogin.DwUin = 0
			}
		} else {
			ResLogin.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_ERROR
			ResLogin.DwUin = 0
		}
		if ResLogin.DwUin > 0 {
			if OldPlayer, ok := G_GameLogicPtr.M_Players[ResLogin.DwUin]; ok {
				G_GameLogicPtr.ReplaceExistPlayerAndAgent(a, OldPlayer)
				OldPlayer.PAMgr.InitActiveMgr(OldPlayer)
			} else {
				player := G_GameLogicPtr.FindOfflinePlayer(ResLogin.DwUin)
				if player != nil {
					G_GameLogicPtr.RebindPlayerAndAgent(a, player)
					player.PAMgr.InitActiveMgr(player)
				} else {
					G_GameLogicPtr.CreateNewPlayer(a, detail.UserName)
				}
			}

		}
		data, _ := proto.Marshal(ResLogin)
		G_getGameLogic().PackResInfo(a, "ResLogin", data)

	case "ReqServerTime":
		detail := &msg.ReqServerTime{}
		proto.Unmarshal(buf, detail)
		res := &msg.ResServerTime{}
		res.ServerTime = (int32)(time.Now().Unix())
		data, _ := proto.Marshal(res)
		G_getGameLogic().PackResInfo(a, "ResServerTime", data)
	case "ReqOfflineReconnect":
		RunNetProcessByKey(m.GetFunc(), []interface{}{a, buf})
	default:
		p, ok := internal.Agents[a]
		if ok && p != G_GameLogicPtr.NotInitPlayer {
			RunNetProcessByKey(m.GetFunc(), []interface{}{a, buf})
		}

	}

}
